Lobbin loco - #39
Open
pkatzfey wants to merge 126 commits into
Open
Conversation
Merge fixes from main
Update from FRC5010Example
commit b7f64a1 Author: Curt <clrozeboom@gmail.com> Date: Sun Oct 5 15:10:09 2025 -0400 Remove butterbup commit 98e3a69 Merge: 80b8424 89a320a Author: Curt <clrozeboom@gmail.com> Date: Sun Oct 5 14:50:00 2025 -0400 Merge branch 'main' into 7-swerve-updates commit 80b8424 Author: CameronSkea <cameronskea@icloud.com> Date: Wed Oct 1 17:34:36 2025 -0400 updates commit 34af230 Merge: 32ac53c 9c5d9d2 Author: 5010 Tiger Dynasty <roboticsteam.fhs@gmail.com> Date: Wed Oct 1 17:06:27 2025 -0400 Merge pull request #10 from FRC5010/main Merge fixes from main
for robert
Reorganized import statements in ExampleRobot.java and ExampleSubsystem.java for improved readability and consistency. No functional changes were made.
…into LobbinLoco
…into LobbinLoco
ModuleIOSpark only set inputs.turnAbsolutePosition and never set inputs.turnPosition, which defaults to zero. On the real robot Module.getAngle() and Module.runSetpoint's cosineScale() use turnPosition, so the module looked like it was always at 0 degrees. The drive speed was then scaled by cos(targetAngle - 0): - forward (0 deg): cos 0 = 1.0 -> full drive - rotate (~45 deg): cos 45 ~= 0.7 -> drives - strafe (90 deg): cos 90 = 0.0 -> no drive so the wheels rotated sideways but never spun, and reported module angles (odometry) were stuck at 0. These modules steer on the absolute encoder with no separate relative turn encoder, so mirror turnPosition from turnAbsolutePosition. Simulation was unaffected because getAngle()/cosineScale use turnAbsolutePosition in sim. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NuiJsExocjmTcG2zKNJNYx
Documents the Spotless/JDK build workaround, the JSON-config-driven multi-robot selection flow, and the swerve drivetrain architecture (YAGSL vs AKit, the Spark IO reading DriveConstants instead of JSON, the dual odometry threads, and absolute-encoder steering pitfalls). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NuiJsExocjmTcG2zKNJNYx
…agnostics
ModuleIOSpark now reads its hardware identity from the deploy JSON
(AkitSwerveConfig / SwerveModuleConstants) instead of DriveConstants:
- drive/steer CAN IDs, drive gear ratio, drive current limit
- drive/steer motor inversion and absolute-encoder inversion
- absolute encoder zero offset (JSON absoluteOffset -> EncoderOffset ->
zeroRotation), so per-module offsets can finally be set from config to move
modules off the +/-180 wrap seam.
Closed-loop gains and the steer wrapping stay in DriveConstants because they
are in AdvantageKit units (wheel rad/s, module radians), not the YAGSL-native
gains stored elsewhere in the JSON.
Diagnostics for swerve commissioning:
- ModuleIO gains turnRawAbsolutePosition (pre-offset encoder reading). Point a
wheel forward and copy its logged degrees into the module's absoluteOffset.
- AkitSwerveDrive logs Drive/Diag/Module*/{Setpoint,Measured,AngleError}* and
chassis speeds setpoint/measured every loop, independent of enable state, so
wrong-direction and tracking issues are visible even in disabled logs (where
SwerveStates/Setpoints is blanked).
Spark branch now constructs ModuleIOSpark(config, moduleConstants).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NuiJsExocjmTcG2zKNJNYx
ModuleIOSpark now reads the drive and steer closed-loop gains from the deploy
JSON (constants.DriveMotorGains / SteerMotorGains, which AkitSwerveConfig builds
from driveMotorControl / steerMotorControl) instead of DriveConstants. The akit
drivetrain owns its own akit-unit PID; it is not the YAGSL pidfproperties gain.
Only universal akit constants (encoder factors, steer wrap range, steer current,
odometry frequency) remain in DriveConstants.
Buttercup JSON now holds proper akit-unit gains (steer kP 2.0, drive kV 0.1)
rather than the YAGSL copies (steer p 0.02).
Black akit config was {"type":"SparkTalon"}, which instantiates a TalonFX drive
motor - wrong for black's NEO-on-SparkMax hardware. Set type "Spark" with a full
constants block from black's YAGSL config (CAN IDs FL 1/2, FR 7/8, BL 3/4,
BR 5/6; drive inverted -> invertLeftSide/invertRightSide true; encoderInverted
true). Switch black_robot/robot.json driveType to AKIT_SWERVE_DRIVE.
Black's absoluteOffsets are still 0 and will need azimuth-offset calibration
(point wheels forward, read Drive/Module*/TurnRawAbsolutePosition) before it
drives cleanly.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NuiJsExocjmTcG2zKNJNYx
Mirror the ModuleIOSpark fixes onto the SparkTalon steer side: - Populate inputs.turnPosition (= turnAbsolutePosition) and the turnRawAbsolutePosition diagnostic. Without turnPosition, Module.getAngle()/cosineScale saw the wheel as always at 0 deg, so drive was scaled by cos(targetAngle) (no strafe) and odometry module angles were stuck. - Read steer motor inversion, encoder inversion, steer PID, and the absolute encoder offset from the deploy JSON (constants.SteerMotorInverted / EncoderInverted / SteerMotorGains / EncoderOffset) instead of DriveConstants, matching the now config-driven drive side and ModuleIOSpark. - Keep universal akit constants (encoder factors, wrap range, steer current, odometry frequency) in DriveConstants. No deploy config currently selects "SparkTalon", so this is a correctness fix so the type works if selected later. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NuiJsExocjmTcG2zKNJNYx
The flywheel stop logic called lowerFlyWheel.set(0)/upperFlyWheel.set(0) inside Runnable lambdas (finallyDo and Commands.runOnce). FlyWheel.set() returns a RunCommand that must be scheduled to take effect, so those returned commands were silently discarded and the motors were never commanded to zero. On button release the held set(SPEED) RunCommand is interrupted but does not zero its output, leaving the flywheels spinning. Bind the stop command to onFalse directly (matching the working feeder pattern), so the set(0) command is actually scheduled. Drop the dead set(0) calls from the whileTrue finallyDo blocks, leaving only the LED reset there. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HmeQnHETe7J9KFoKXG56PM
Replace direct button constants with createXButton/createLeftBumper/createRightBumper/createStartButton bindings, consolidate multiple shooter stop onFalse handlers into a single binding, and invert feeder motor speeds for the corresponding button actions. These updates clarify controller mappings and ensure feeder/shooter commands and LED updates trigger and stop correctly.
Replace the hard-coded SmartMotorController/FlyWheel construction in
FeederSubsystem with the config-driven GenericSubsystem pattern used by
UpperFlyWheel: the constructor now calls super("feeder.json") and pulls
the FlyWheel out of the devices map by name.
Add the matching deploy configs (yams_shooter device) for both the
black_robot and buttercup_swerve robot directories, reproducing the
previous feeder tuning: Spark/Neo on CAN 12, 3x4 reduction, 40A stator
limit, brake mode, 0.25s closed-loop ramp, profiled closed loop
(p=0.00016541, 5000 rpm / 2500 rps^2), 3in diameter, 1 lb, +/-500 rpm
soft limits.
Verified in simulation: the feeder mechanism loads and telemeters under
/Mechanisms/feeder alongside the flywheels, and robot startup completes
with no parse errors.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HmeQnHETe7J9KFoKXG56PM
Replace the feeder LED behavior so it shows a sweeping green "laser" while feeding and returns to the alliance-color background when done. - Add LEDStrip.getLaserPattern(color, width, speed): a narrow colored band that scrolls along the segment over an unlit background. - Feeder A/Start buttons now light FEEDER_LED with the green laser on press and deactivate the segment on release (instead of leaving it solid red and active), so the left half reverts to alliance color. - Remove the teleop-enabled trigger that force-activated FEEDER_LED with its default unlit pattern, which blanked the left half of the strip during teleop (and leaked a perpetual command each enable). Drop the now-unused DriverStation, Trigger, and Seconds imports. Verified: compiles and the robot starts cleanly in simulation. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HmeQnHETe7J9KFoKXG56PM
- getBand: the third mask step used bandCenter - percentWidth/2, which duplicated the second step's key (Map.of throws on duplicate keys) and was geometrically wrong. Use bandCenter + percentWidth/2 so the band's right edge is correct and the keys are distinct. - addSegment overloads: the range parameter was named "length" and documented as a length, but it is passed straight to AddressableLEDBuffer.createView(start, endIndex), whose second argument is an inclusive end index. Rename the parameter to endIndex and fix the Javadoc so the contract matches the (correct) behavior the config path already relies on. No behavior change to existing callers. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HmeQnHETe7J9KFoKXG56PM
Instrument per-module steering so a wheel that fails to reach its commanded rotation can be diagnosed. - YAGSLSwerveDrivetrain.periodic() now logs Swerve/Diag/* every loop when the YAGSL telemetry verbosity is HIGH or above (same flag the rest of the swerve high-verbosity logging uses): desired vs measured azimuth and error, absolute-minus-relative encoder divergence, steer applied output, voltage and velocity, the absolute-encoder read-issue flag, a derived per-module "misaligned" flag, and the max absolute error. Desired angle comes from YAGSL's post-optimization commanded state. Logged through AdvantageKit so it lands in the .wpilog for replay, not just live NT. - Add SwerveDriveFunctions.pointModulesAt(degrees) (YAGSL override points every module's azimuth, drive motors untouched). - Add GenericSwerveDrivetrain.azimuthStepTestCommand(): a deterministic routine that steps all modules through a fixed angle sequence with a fixed dwell, logging Swerve/Diag/StepTest/targetDeg, for on-blocks diagnosis. Verified in simulation: all Swerve/Diag/* outputs are recorded with no periodic exceptions. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HmeQnHETe7J9KFoKXG56PM
- Expose azimuthStepTestCommand() on GenericDrivetrain (default no-op, overridden by GenericSwerveDrivetrain) and bind it to the driver A button in BlackRobot's test-mode bindings (configureAltButtonBindings), so the deterministic azimuth diagnostic can be run on blocks in Test. - Fix GenericSwerveModuleInfo.expectedSteerDegrees so the Glass "expected" dial shows the actual commanded (post-optimization) steer angle from YAGSL telemetry instead of the measured state angle. Falls back to the measured angle before any command has been issued. Verified: compiles and the robot starts and loops cleanly in simulation. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HmeQnHETe7J9KFoKXG56PM
Register the deterministic azimuth diagnostic on SmartDashboard from the GenericSwerveDrivetrain constructor so it can be triggered from the dashboard (while enabled, robot on blocks) without entering Test mode, in addition to the Test-mode A-button binding. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HmeQnHETe7J9KFoKXG56PM
Brings in the SparkFishers work (feeder/flywheel JSON-driven subsystems, driver button binding refactor, LED green-laser sweep, swerve azimuth diagnostics + step-test command and dashboard button, controller axis 2<->4 remap). This branch stays on AdvantageKit swerve: SparkFishers touches no robot.json or akit config, so both robots keep driveType AKIT_SWERVE_DRIVE with the "Spark" module IO. The only content overlap, buttercup driver_right_x.json, auto-resolved to SparkFishers's channel 2 with invert false (both branches set invert false). Note: the merged Azimuth Step Test drives modules via SwerveDriveFunctions.pointModulesAt, which only YAGSLSwerveDrivetrain overrides, so the step test is currently a no-op on the akit drivetrains. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NuiJsExocjmTcG2zKNJNYx
SparkFishers' azimuth step test drives modules via SwerveDriveFunctions.pointModulesAt, which only YAGSL overrode, so it was a no-op on the akit drivetrains. Override it in AkitSwerveDrive: - Add Module.pointAt(Rotation2d): commands the steer position directly with the drive stopped, bypassing runSetpoint's nearest-equivalent optimize so the module physically rotates to the commanded angle (not a 180 deg flip) - which is what the diagnostic needs to measure. - AkitSwerveDrive.pointModulesAt points all modules and records the commanded angle in lastSetpointStates, so the always-on Drive/Diag/Module*/AngleErrorDeg reports target-vs-measured during the test. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NuiJsExocjmTcG2zKNJNYx
Second merge of SparkFishers, which adds "Updates to Elphaba CAN" (34ce7ba): new black_robot YAGSL module CAN IDs plus BlackRobot/GenericDrivetrain/ GenericSwerveDrivetrain/LEDStrip tweaks. Black runs on AdvantageKit, which reads akit_swerve_drivetrain.json (not the YAGSL modules), so propagate the updated CAN IDs into black's akit config: frontLeft drive 18/steer 2, frontRight drive 17/steer 6, backLeft drive 16/steer 3, backRight drive 4/steer 15. black_robot/robot.json stays driveType AKIT_SWERVE_DRIVE. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NuiJsExocjmTcG2zKNJNYx
Third merge of SparkFishers ("Other updates", 62f55df): swaps black backRight
YAGSL ids (drive 15 / angle 4), bumps the YAGSL angle PID, and adjusts
BlackRobot. Black runs on AdvantageKit (reads akit_swerve_drivetrain.json), so
sync black's akit backRight to drive 15 / steer 4. The YAGSL angle-PID bump is
not propagated: the akit steer loop uses a different unit basis (akit steer kP
stays 2.0). black_robot/robot.json stays driveType AKIT_SWERVE_DRIVE.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NuiJsExocjmTcG2zKNJNYx
tools/swerve_log_analysis.py reads an AdvantageKit .wpilog (stdlib only) and summarizes the Swerve/Diag/* signals: per-module desired/measured angle and error, absolute-vs-relative encoder gap, absolute-encoder read issues, and steer effort. It lists the timestamps where a module is flagged misaligned (settled but off target) with the concurrent signals so a miss can be mapped to encoder desync, a read failure, output saturation, or weak PID. Warns when a log was never enabled. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HmeQnHETe7J9KFoKXG56PM
Brings in 8516b88 (tools/swerve_log_analysis.py), a stdlib-only AdvantageKit .wpilog analyzer for the Swerve/Diag/* azimuth signals. Adds only the tool; no code or config changes. This branch stays on AKIT_SWERVE_DRIVE. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NuiJsExocjmTcG2zKNJNYx
Switch the robot deploy config to the YAGSL swerve drive. Implement deterministic per-move steering in YAGSLSwerveDrivetrain.pointModulesAt by tracking the last target, synchronizing module encoders on a new target, and issuing a zero-drive setDesiredState for a fresh, re-seeded command; repeated calls hold angle via setAngle. Bump BuildConstants (git revision/sha/branch/dates/build time). Include minor whitespace/javadoc formatting tweaks in ModuleIO/ModuleIOSpark.
Setup for Logitech JS
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
New Computer setup for Team Black